<template>
  <div class="props-table">
    <div
      v-for="(item, key) in finalProps"
      :id="`item-${key}`"
      :key="key"
      class="prop-item"
      :class="{ 'no-text': !item.text }"
    >
      <span v-if="item.text" class="label">{{ item.text }}</span>
      <div :class="`prop-component component-${item.component}`">
        <!-- :[item.valueProp]="item.value" -->
        <component :is="item.component" v-model="item.value" v-bind="item.extraProps" v-on="item.events">
          <template v-if="item.options">
            <component
              :is="item.subComponent"
              v-for="(option, index) in item.options"
              :key="index"
              v-bind="option.props"
            >
              <template v-if="option.text">
                <render-vnode :v-node="option.text" />
              </template>
            </component>
          </template>
        </component>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { ElInput, ElInputNumber, ElSlider, ElRadioGroup, ElRadioButton, ElSelect, ElOption } from 'element-plus'
import { VNode } from 'vue'
import RenderVnode from './RenderVnode'
import ColorPicker from './ColorPicker.vue'
import IconSwitch from './IconSwitch.vue'
import ShadowPicker from './ShadowPicker.vue'
import ImageProcesser from './ImageProcesser.vue'
import BackgroundProcesser from './BackgroundProcesser.vue'

// 渲染表单所需要的数据结构
export interface FormProps {
  component: string // 渲染表单对应的组件
  subComponent?: string // 渲染表单对应的子组件；如果有的话
  value: string // 表单组件渲染的值
  extraProps?: { [key: string]: any } // 渲染表单组件的额外参数
  text?: string // 表单组件标题
  valueProp?: string // 自定义动态绑定value的参数；:[item.valueProp]="item.value"； 在element上大多数都是 v-model 所以暂时无用
  options?: { props: { label?: any; value?: any }; text?: string | VNode }[] // 渲染表单子组件需要的参数，label和value按组件需要填充
  eventName: string // 自定义表单组件事件名称；默认 change
  events: { [key: string]: (e: any) => void } // 表单组件事件定义
}
export default defineComponent({
  components: {
    ElInput,
    ElInputNumber,
    ElSlider,
    ElRadioGroup,
    ElRadioButton,
    ElSelect,
    ElOption,
    RenderVnode,
    ColorPicker,
    IconSwitch,
    ShadowPicker,
    ImageProcesser,
    BackgroundProcesser
  }
})
</script>

<script lang="ts" setup>
import { reduce } from 'lodash-es'
import { mapPropsToForms } from '@/propsMap'
import { AllComponentProps } from '@isameng/lowcode-components'

const props = defineProps<{
  props: AllComponentProps
}>()

const emits = defineEmits(['change'])

const finalProps = computed(() => {
  return reduce(
    props.props,
    (result, value, key) => {
      const item = mapPropsToForms[key as keyof AllComponentProps]
      if (item) {
        const { eventName = 'change', initialTransform, afterTransform } = item
        const newItem: FormProps = {
          ...item,
          value: initialTransform ? initialTransform(value) : value,
          eventName,
          events: {
            [eventName]: (e: any) => {
              emits('change', { key, value: afterTransform ? afterTransform(e) : e })
            }
          }
        }
        result[key] = newItem
      }
      return result
    },
    {} as { [key: string]: FormProps }
  )
})
</script>

<style lang="scss" scoped>
.props-table {
  padding: 12px 12px;
}
.prop-item {
  display: flex;
  margin-bottom: 10px;
  align-items: center;
}
.label {
  width: 28%;
}
.prop-component {
  width: 70%;
}
.prop-item.no-text {
  display: inline-block;
  margin: 0 10px 10px 0;
}
#item-fontWeight {
  margin-left: 28%;
}
.component-el-select .el-select {
  width: 150px;
}
.prop-component.component-shadow-picker,
.prop-component.component-image-processer,
.prop-component.component-background-processer {
  width: 100%;
}
</style>
